﻿using System;
using System.Collections.Generic;
using System.Diagnostics;

namespace Teal.Compiler {

    #region ISymbol

    /// <summary>
    /// 表示一个符号对象（如变量、参数、表达式和成员引用等）。
    /// </summary>
    public interface ISymbol {

        ///// <summary>
        ///// 载入当前符号的值，返回代表此操作的表达式。
        ///// </summary>
        ///// <param name="context">包含所有解析状态的上下文对象。</param>
        ///// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
        ///// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
        ///// <returns>返回代表此操作的表达式。</returns>
        //Expression getValue(ResolveContext context, Expression instance, Node srcNode);

        ///// <summary>
        ///// 存储当前符号的值，返回代表此操作的表达式。
        ///// </summary>
        ///// <param name="context">包含所有解析状态的上下文对象。</param>
        ///// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
        ///// <param name="value">要设置的值表达式。</param>
        ///// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
        ///// <returns>返回代表此操作的表达式。</returns>
        //Expression setValue(ResolveContext context, Expression instance, Expression value, Node srcNode);

        ///// <summary>
        ///// 载入当前符号的地址，返回代表此操作的表达式。
        ///// </summary>
        ///// <param name="context">包含所有解析状态的上下文对象。</param>
        ///// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
        ///// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
        ///// <returns>返回代表此操作的表达式。</returns>
        //Expression addressOf(ResolveContext context, Expression instance, Node srcNode);

        ///// <summary>
        ///// 调用当前符号，返回代表此操作的表达式。
        ///// </summary>
        ///// <param name="context">包含所有解析状态的上下文对象。</param>
        ///// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
        ///// <param name="arguments">调用的参数。</param>
        ///// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
        ///// <returns>返回代表此操作的表达式。</returns>
        //Expression invoke(ResolveContext context, Expression instance, FuncCallExpression.Argument arguments, Node srcNode);

    }

    #endregion

    #region SpecailSymbol

    /// <summary>
    /// 表示一个成员引用组。
    /// </summary>
    public class MemberReferenceGroup : List<MemberReference>, ISymbol {

        #region 对象池

        static MemberReferenceGroup[] _objectPool = new MemberReferenceGroup[128];
        static int _objectPoolLength;

        /// <summary>
        /// 当对象池中申请一个新的对象。
        /// </summary>
        /// <param name="capicity"></param>
        /// <returns></returns>
        public static MemberReferenceGroup alloc(int capicity = 1) {
            if (_objectPoolLength == 0) {
                return new MemberReferenceGroup(capicity);
            }
            return _objectPool[_objectPoolLength--];
        }

        /// <summary>
        /// 将指定的对象放入对象池。
        /// </summary>
        /// <param name="capicity"></param>
        /// <returns></returns>
        public static void free(MemberReferenceGroup value) {
            if (_objectPoolLength < _objectPool.Length) {
                value.Clear();
                _objectPool[++_objectPoolLength] = value;
            }
        }

        #endregion

        /// <summary>
        /// 初始化 <see cref="MemberReferenceGroup"/> 类的新实例。
        /// </summary>
        public MemberReferenceGroup(int capicity = 1)
            : base(capicity) {

        }

        /// <summary>
        /// 找出当前方法中符合指定要求的成员。
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public MemberReferenceGroup findAll(Predicate<MemberReference> predicate) {

            int unmatchCount = 0;
            foreach (var member in this) {
                if (!predicate(member)) {
                    unmatchCount++;
                }
            }

            // 大部分情况，成员全部符合要求，为节约内存，先判断是否可直接使用继承的成员组。
            if (unmatchCount == 0) {
                return this;
            }

            // 全部成员不符合要求。
            if (Count == unmatchCount) {
                return null;
            }

            MemberReferenceGroup result = new MemberReferenceGroup(Count - unmatchCount);

            // 筛选出符合的项。
            foreach (var member in this) {
                if (predicate(member)) {
                    result.Add(member);
                }
            }

            return result;
        }

    //    /// <summary>
    //    /// 载入当前符号的值，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.getValue(ResolveContext context, Expression instance, Node srcNode) {
    //        return new ResolvedMethodReferenceGroupExpression() {
    //            target = this,
    //            instance = instance,
    //            type = PredefinedTypes.System_Func
    //        };
    //    }

    //    /// <summary>
    //    /// 存储当前符号的值，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="value">要设置的值表达式。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.setValue(ResolveContext context, Expression instance, Expression value, Node srcNode) {
    //        // 报错。
    //        return ((ISymbol)this[0]).setValue(context, instance, value, srcNode);
    //    }

    //    /// <summary>
    //    /// 载入当前符号的地址，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.addressOf(ResolveContext context, Expression instance, Node srcNode) {
    //        // 报错。
    //        return ((ISymbol)this[0]).addressOf(context, instance, srcNode);
    //    }

    //    /// <summary>
    //    /// 调用当前符号，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="arguments">调用的参数。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.invoke(ResolveContext context, Expression instance, FuncCallExpression.Argument arguments, Node srcNode) {
    //        return ResolveHelper.invoke(context, this, instance, arguments, srcNode);
        //}

    }

    /// <summary>
    /// 用于创建成员组的工具。对于元素仅有一个或零个时可节约内存。
    /// </summary>
    public struct MemberReferenceGroupBuilder {

        /// <summary>
        /// 获取当前生成的组对象。当无元素时，值为 null，当有一个元素时，值为该元素，当有多个元素时，值为元素列表。
        /// </summary>
        public ISymbol result;

        /// <summary>
        /// 向当前组添加成员。
        /// </summary>
        /// <param name="member"></param>
        public void add(MemberReference member) {
            if (result == null) {
                result = member;
            } else {
                MemberReferenceGroup list = result as MemberReferenceGroup;
                if (list == null) {
                    list = MemberReferenceGroup.alloc();
                    list.Add((MemberReference)result);
                    result = list;
                }
                list.Add(member);
            }
        }

    }

    #endregion

    #region Nodes

    ///// <summary>
    ///// 表示一个变量。
    ///// </summary>
    //public partial class Variable : ISymbol {

    //    /// <summary>
    //    /// 载入当前符号的值，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.getValue(ResolveContext context, Expression instance, Node srcNode) {
    //        Debug.Assert(instance == null || instance  == Expression.empty);

    //        // 检查变量是否已声明和赋值。
    //        isEverUsed = true;
    //        if (declareState != State.on) {
    //            Compiler.error(ErrorCode.none, String.Format("无法在声明之前使用局部变量“{0}”", name.value), srcNode);
    //        } else if (!isAssigned(context)) {
    //            Compiler.error(ErrorCode.none, String.Format("无法在赋值之前使用局部变量“{0}”", name.value), srcNode);
    //        }

    //        // 常量直接返回其值。
    //        if (variableType == VariableType.constLocal) {
    //            return initialiser;
    //        }

    //        return new ResolvedLoadVariableExpression() {
    //            target = this
    //        };
    //    }

    //    /// <summary>
    //    /// 存储当前符号的值，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="value">要设置的值表达式。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.setValue(ResolveContext context, Expression instance, Expression value, Node srcNode) {
    //        Debug.Assert(instance == null || instance  == Expression.empty);

    //        // 检查变量是否已声明。
    //        isEverUsed = true;
    //        if (declareState != State.on) {
    //            Compiler.error(ErrorCode.none, String.Format("无法在声明之前使用局部变量“{0}”", name.value), srcNode);
    //            return null;
    //        }

    //        // 常量无法赋值。
    //        if (variableType == VariableType.constLocal) {
    //            Compiler.error(ErrorCode.none, String.Format("无法在向常量“{0}”赋值", name.value), srcNode);
    //            return null;
    //        }

    //        setAssigned(context);

    //        var resolvedValue = value.resolveAsValue(context, resolvedType);
    //        if (resolvedValue == null) {
    //            return null;
    //        }

    //        return new ResolvedStoreVariableExpression() {
    //            target = this,
    //            value = resolvedValue
    //        };
    //    }

    //    /// <summary>
    //    /// 载入当前符号的地址，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.addressOf(ResolveContext context, Expression instance, Node srcNode) {
    //        Debug.Assert(instance == null || instance  == Expression.empty);

    //        // 检查变量是否已声明和赋值。
    //        isEverUsed = true;
    //        if (declareState != State.on) {
    //            Compiler.error(ErrorCode.none, String.Format("无法在声明之前使用局部变量“{0}”", name.value), srcNode);
    //        }

    //        return new ResolvedAddressOfVariableExpression() {
    //            target = this
    //        };
    //    }

    //    /// <summary>
    //    /// 调用当前符号，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="arguments">调用的参数。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.invoke(ResolveContext context, Expression instance, FuncCallExpression.Argument arguments, Node srcNode) {
    //        isEverUsed = true;
    //        return ResolveHelper.invoke(context, ((ISymbol)this).getValue(context, instance, srcNode), arguments, srcNode);
    //    }

    //}

    ///// <summary>
    ///// 表示一个函数参数。
    ///// </summary>
    //public partial class Parameter : ISymbol {

    //    /// <summary>
    //    /// 载入当前符号的值，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.getValue(ResolveContext context, Expression instance, Node srcNode) {
    //        Debug.Assert(instance == null || instance  == Expression.empty);

    //        // 检查输出参数是否已赋值。
    //        isEverUsed = true;
    //        if (!isAssigned(context)) {
    //            Compiler.error(ErrorCode.none, String.Format("无法在赋值之前使用输出参数“{0}”", name.value), srcNode);
    //        }

    //        return new ResolvedLoadParameterExpression() {
    //            target = this
    //        };
    //    }

    //    /// <summary>
    //    /// 存储当前符号的值，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="value">要设置的值表达式。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.setValue(ResolveContext context, Expression instance, Expression value, Node srcNode) {
    //        Debug.Assert(instance == null || instance  == Expression.empty);

    //        isEverUsed = true;
    //        setAssigned(context);

    //        var resolvedValue = value.resolveAsValue(context, resolvedType);
    //        if (resolvedValue == null) {
    //            return null;
    //        }

    //        return new ResolvedStoreParameterExpression() {
    //            target = this,
    //            value = resolvedValue
    //        };
    //    }

    //    /// <summary>
    //    /// 载入当前符号的地址，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.addressOf(ResolveContext context, Expression instance, Node srcNode) {
    //        Debug.Assert(instance == null || instance  == Expression.empty);

    //        isEverUsed = true;

    //        return new ResolvedAddressOfParameterExpression() {
    //            target = this
    //        };
    //    }

    //    /// <summary>
    //    /// 调用当前符号，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="arguments">调用的参数。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.invoke(ResolveContext context, Expression instance, FuncCallExpression.Argument arguments, Node srcNode) {
    //        isEverUsed = true;
    //        return ResolveHelper.invoke(context, ((ISymbol)this).getValue(context, instance, srcNode), arguments, srcNode);
    //    }

    //}

    ///// <summary>
    ///// 表示一个常量。
    ///// </summary>
    //public partial class Constant : ISymbol {

    //    /// <summary>
    //    /// 载入当前符号的值，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.getValue(ResolveContext context, Expression instance, Node srcNode) {
    //        Debug.Assert(instance == null || instance  == Expression.empty);
    //        return this;
    //    }

    //    /// <summary>
    //    /// 存储当前符号的值，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="value">要设置的值表达式。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.setValue(ResolveContext context, Expression instance, Expression value, Node srcNode) {
    //        Debug.Assert(instance == null || instance  == Expression.empty);
    //        Compiler.error(ErrorCode.none, "无法向常量赋值；只能向局部变量、参数、字段、属性或索引器赋值", srcNode);
    //        return null;
    //    }

    //    /// <summary>
    //    /// 载入当前符号的地址，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.addressOf(ResolveContext context, Expression instance, Node srcNode) {
    //        Debug.Assert(instance == null || instance  == Expression.empty);
    //        Compiler.error(ErrorCode.none, "无法获取常量的地址；只能获取局部变量、参数、字段的地址", srcNode);
    //        return null;
    //    }

    //    /// <summary>
    //    /// 调用当前符号，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="arguments">调用的参数。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.invoke(ResolveContext context, Expression instance, FuncCallExpression.Argument arguments, Node srcNode) {
    //        Debug.Assert(instance == null || instance  == Expression.empty);
    //        return ResolveHelper.invoke(context, this, arguments, srcNode);
    //    }

    //}

    /// <summary>
    /// 表示一个成员（如方法、字段、类型、包等）引用。
    /// </summary>
    public abstract partial class MemberReference : ISymbol {

    //    private void reportUsedAsExpressionError(Node srcNode) {
    //        Compiler.error(ErrorCode.none, String.Format("“{0}”是{1}，但被当作变量使用", fullName, memberType.getReadableName()), srcNode);
    //    }

    //    /// <summary>
    //    /// 载入当前符号的值，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.getValue(ResolveContext context, Expression instance, Node srcNode) {
    //        Debug.Assert(instance == null || instance  == Expression.empty);
    //        reportUsedAsExpressionError(srcNode);
    //        return null;
    //    }

    //    /// <summary>
    //    /// 存储当前符号的值，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="value">要设置的值表达式。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.setValue(ResolveContext context, Expression instance, Expression value, Node srcNode) {
    //        Debug.Assert(instance == null || instance  == Expression.empty);
    //        reportUsedAsExpressionError(srcNode);
    //        return null;
    //    }

    //    /// <summary>
    //    /// 载入当前符号的地址，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.addressOf(ResolveContext context, Expression instance, Node srcNode) {
    //        Debug.Assert(instance == null || instance  == Expression.empty);
    //        reportUsedAsExpressionError(srcNode);
    //        return null;
    //    }

    //    /// <summary>
    //    /// 调用当前符号，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="arguments">调用的参数。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.invoke(ResolveContext context, Expression instance, FuncCallExpression.Argument arguments, Node srcNode) {
    //        Debug.Assert(instance == null || instance  == Expression.empty);
    //        Compiler.error(ErrorCode.none, String.Format("无法像方法一样调用{0}“{1}”", memberType.getReadableName(), fullName), srcNode);
    //        return null;
    //    }

    //}

    ///// <summary>
    ///// 表示一个字段引用。
    ///// </summary>
    //public partial class FieldReference : ISymbol {

    //    /// <summary>
    //    /// 载入当前符号的值，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.getValue(ResolveContext context, Expression instance, Node srcNode) {
    //        isEverUsed = true;

    //        ResolveHelper.checkInstance(this, context, ref instance, srcNode);

    //        // 确保字段已解析。
    //        if (memberDefinition != null && !((FieldDefinition)memberDefinition).resolveField(this, variable)) {
    //            Compiler.error(ErrorCode.circuleFieldInitializer, String.Format("检测到“{0}”和“{1}”有循环初始化依赖", context.currentMemberDefinition.memberReference.fullName, fullName), ((FieldReference)context.currentMemberDefinition.memberReference).variable.name);
    //            return null;
    //        }

    //        // 常量字段直接返回值。
    //        if (modifiers.hasFlag(Modifiers.@const)) {
    //            Debug.Assert(instance == null || instance  == Expression.empty);
    //            if (parentContainer.memberType == MemberType.@enum) {
    //                return new EnumConstant(this);
    //            }

    //            return initialValue;
    //        }

    //        return new ResolvedLoadFieldExpression() {
    //            instance = instance,
    //            target = this
    //        };
    //    }

    //    /// <summary>
    //    /// 存储当前符号的值，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="value">要设置的值表达式。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.setValue(ResolveContext context, Expression instance, Expression value, Node srcNode) {
    //        isEverUsed = true;
    //        isEverAssigned = true;

    //        ResolveHelper.checkInstance(this, context, ref instance, srcNode);

    //        // 常量字段无法设置值。
    //        if (modifiers.hasFlag(Modifiers.@const)) {
    //            Compiler.error(ErrorCode.none, String.Format("无法向常量“{0}”赋值；只能向局部变量、参数、字段、属性或索引器赋值", fullName), srcNode);
    //            return null;
    //        }

    //        // final 字段只能在类内部设置。
    //        if (modifiers.hasFlag(Modifiers.final)) {

    //            // 检查当前范围是否可以访问目标类型。
    //            if (!ResolveHelper.canAccessProtected(context.currentMemberDefinition, this)) {
    //                Compiler.error(ErrorCode.none, String.Format("无法在类型外部向最终字段“{0}”赋值", fullName), srcNode);
    //                return null;
    //            }

    //            // 检查是否可以使用指定限定类型访问。
    //            if (instance != null && !ResolveHelper.canAccessProtected(context.currentMemberDefinition, instance)) {
    //                Debug.Assert(context.currentMemberDefinition.memberReference.parentType != null, "如果当前成员不是类型，应该无法访问 protected 字段");
    //                Compiler.error(ErrorCode.none, String.Format("无法通过类型“{0}”向最终字段“{1}”赋值，应使用“{2}”或其子类", instance.resolvedType, fullName, context.currentMemberDefinition.memberReference.parentContainer.fullName), srcNode);
    //                return null;
    //            }

    //        }

    //        var resolvedValue = value.resolveAsValue(context, returnType);
    //        if (resolvedValue == null) {
    //            return null;
    //        }

    //        return new ResolvedStoreFieldExpression() {
    //            instance = instance,
    //            target = this,
    //            value = resolvedValue
    //        };
    //    }
        
    //    /// <summary>
    //    /// 载入当前符号的地址，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.addressOf(ResolveContext context, Expression instance, Node srcNode) {
    //        isEverUsed = true;

    //        ResolveHelper.checkInstance(this, context, ref instance, srcNode);

    //        // 常量字段无法设置值。
    //        if (modifiers.hasFlag(Modifiers.@const)) {
    //            Compiler.error(ErrorCode.none, String.Format("无法获取常量“{0}”的地址；只能获取局部变量、参数、字段的地址", fullName), srcNode);
    //            return null;
    //        }

    //        return new ResolvedAddressOfFieldExpression() {
    //            instance = instance,
    //            target = this
    //        };
    //    }

    //    /// <summary>
    //    /// 调用当前符号，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="arguments">调用的参数。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.invoke(ResolveContext context, Expression instance, FuncCallExpression.Argument arguments, Node srcNode) {
    //        isEverUsed = true;
    //        return ResolveHelper.invoke(context, ((ISymbol)this).getValue(context, instance, srcNode), arguments, srcNode);
    //    }

    }

    ///// <summary>
    ///// 表示一个属性引用。
    ///// </summary>
    //public partial class PropertyReference : ISymbol {

    //    /// <summary>
    //    /// 载入当前符号的值，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.getValue(ResolveContext context, Expression instance, Node srcNode) {

    //        ResolveHelper.checkInstance(this, context, ref instance, srcNode);

    //        // 检查访问权限。
    //        if (getAccessibility == Modifiers.none) {
    //            Compiler.error(ErrorCode.none, String.Format("无法获取只写属性或索引器“{0}”；缺少“get”访问器", fullName), srcNode);
    //            return null;
    //        }

    //        if (!ResolveHelper.canAccessProperyAccessor(context.currentMemberDefinition, this, getAccessibility)) {
    //            Compiler.error(ErrorCode.none, String.Format("无法获取属性或索引器“{0}”的值，因为“get”访问器是{1}", fullName, parentContainer.fullName, getAccessibility.getAcccessibilityReadableName()), srcNode);
    //            return null;
    //        }

    //        if (instance != null && getAccessibility == Modifiers.@protected && !ResolveHelper.canAccessProtected(context.currentMemberDefinition, instance)) {
    //            Debug.Assert(context.currentMemberDefinition.memberReference.parentType != null);
    //            Compiler.error(ErrorCode.none, String.Format("无法通过类型“{0}”获取保护属性或索引器“{1}”的值，应使用“{2}”或其子类", instance.resolvedType, fullName, context.currentMemberDefinition.memberReference.parentType.fullName), srcNode);
    //            return null;
    //        }

    //        return new ResolvedLoadPropertyExpression() {
    //            instance = instance,
    //            target = this
    //        };
    //    }

    //    /// <summary>
    //    /// 存储当前符号的值，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="value">要设置的值表达式。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.setValue(ResolveContext context, Expression instance, Expression value, Node srcNode) {

    //        ResolveHelper.checkInstance(this, context, ref instance, srcNode);

    //        // 检查访问权限。
    //        if (setAccessibility == Modifiers.none) {
    //            Compiler.error(ErrorCode.none, String.Format("无法向只读属性或索引器“{0}”赋值；缺少“set”访问器", fullName), srcNode);
    //            return null;
    //        }

    //        if (!ResolveHelper.canAccessProperyAccessor(context.currentMemberDefinition, this, setAccessibility)) {
    //            Compiler.error(ErrorCode.none, String.Format("无法向属性或索引器“{0}”赋值，因为“set”访问器是{1}", fullName, parentContainer.fullName, setAccessibility.getAcccessibilityReadableName()), srcNode);
    //            return null;
    //        }

    //        if (instance != null && setAccessibility == Modifiers.@protected && !ResolveHelper.canAccessProtected(context.currentMemberDefinition, instance)) {
    //            Debug.Assert(context.currentMemberDefinition.memberReference.parentType != null);
    //            Compiler.error(ErrorCode.none, String.Format("无法通过类型“{0}”向保护属性或索引器“{1}”赋值，应使用“{2}”或其子类", instance.resolvedType, fullName, context.currentMemberDefinition.memberReference.parentType.fullName), srcNode);
    //            return null;
    //        }

    //        var resolvedValue = value.resolveAsValue(context, returnType);
    //        if(resolvedValue == null) {
    //            return null;
    //        }

    //        return new ResolvedStorePropertyExpression() {
    //            instance = instance,
    //            target = this,
    //            value = resolvedValue
    //        };
    //    }

    //    /// <summary>
    //    /// 载入当前符号的地址，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.addressOf(ResolveContext context, Expression instance, Node srcNode) {
    //        Compiler.error(ErrorCode.none, String.Format("无法获取{1}“{0}”的地址；只能获取局部变量、参数、字段的地址", fullName, memberType.getReadableName()), srcNode);
    //        return null;
    //    }

    //    /// <summary>
    //    /// 调用当前符号，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="arguments">调用的参数。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.invoke(ResolveContext context, Expression instance, FuncCallExpression.Argument arguments, Node srcNode) {
    //        return ResolveHelper.invoke(context, ((ISymbol)this).getValue(context, instance, srcNode), arguments, srcNode);
    //    }

    //}

    ///// <summary>
    ///// 表示一个方法引用。
    ///// </summary>
    //public partial class MethodReference : ISymbol {

    //    /// <summary>
    //    /// 获取表示当前方法的 Func 类型。
    //    /// </summary>
    //    /// <returns></returns>
    //    public TypeReference getFuncType() {
    //        TypeReference[] types = new TypeReference[parameters.Length + 1];
    //        types[0] = returnType;
    //        for (int i = 0; i < parameters.Length; i++) {
    //            var type = parameters[i].type;
    //            if (parameters[i].isOutOrRef) {
    //                type = PredefinedTypes.System_Ptr_T.makeGenericType(type);
    //            }
    //            types[i + 1] = type;
    //        }
    //        return PredefinedTypes.System_Func_T.makeGenericType(types);
    //    }

    //    /// <summary>
    //    /// 载入当前符号的值，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.getValue(ResolveContext context, Expression instance, Node srcNode) {

    //        ResolveHelper.checkInstance(this, context, ref instance, srcNode);

    //        checkConstraints();

    //        var result = new ResolvedMethodReferenceExpression();
    //        result.instance = instance;
    //        result.target = this;
    //        result.type = getFuncType();
    //        return result;
    //    }

    //    /// <summary>
    //    /// 存储当前符号的值，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="value">要设置的值表达式。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.setValue(ResolveContext context, Expression instance, Expression value, Node srcNode) {
    //        Compiler.error(ErrorCode.none, String.Format("无法向{1}“{0}”赋值；只能向局部变量、参数、字段、属性或索引器赋值", fullName, memberType.getReadableName()), srcNode);
    //        return null;
    //    }

    //    /// <summary>
    //    /// 载入当前符号的地址，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.addressOf(ResolveContext context, Expression instance, Node srcNode) {
    //        Compiler.error(ErrorCode.none, String.Format("无法获取{1}“{0}”的地址；只能获取局部变量、参数、字段的地址", fullName, memberType.getReadableName()), srcNode);
    //        return null;
    //    }

    //    /// <summary>
    //    /// 调用当前符号，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="arguments">调用的参数。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.invoke(ResolveContext context, Expression instance, FuncCallExpression.Argument arguments, Node srcNode) {
    //        return ResolveHelper.invoke(context, this, instance, arguments, srcNode);
    //    }

    //}

    ///// <summary>
    ///// 所有表达式的抽象基类。
    ///// </summary>
    //public abstract partial class Expression : ISymbol {

    //    /// <summary>
    //    /// 载入当前符号的值，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.getValue(ResolveContext context, Expression instance, Node srcNode) {
    //        Debug.Assert(instance == null || instance  == Expression.empty);
    //        return this;
    //    }

    //    /// <summary>
    //    /// 存储当前符号的值，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="value">要设置的值表达式。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.setValue(ResolveContext context, Expression instance, Expression value, Node srcNode) {
    //        Debug.Assert(instance == null || instance  == Expression.empty);
    //        Compiler.error(ErrorCode.none, "只能向局部变量、参数、字段、属性或索引器赋值", srcNode);
    //        return null;
    //    }

    //    /// <summary>
    //    /// 载入当前符号的地址，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.addressOf(ResolveContext context, Expression instance, Node srcNode) {
    //        Debug.Assert(instance == null || instance  == Expression.empty);
    //        Compiler.error(ErrorCode.none, "只能获取局部变量、参数、字段的地址", this);
    //        return null;
    //    }

    //    /// <summary>
    //    /// 调用当前符号，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="arguments">调用的参数。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.invoke(ResolveContext context, Expression instance, FuncCallExpression.Argument arguments, Node srcNode) {
    //        Debug.Assert(instance == null || instance  == Expression.empty);
    //        return ResolveHelper.invoke(context, this, arguments, srcNode);
    //    }

    //}

    ///// <summary>
    ///// 表示 this 常量。
    ///// </summary>
    //public partial class ThisLiteral : ISymbol {

    //    /// <summary>
    //    /// 载入当前符号的值，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.getValue(ResolveContext context, Expression instance, Node srcNode) {
    //        Debug.Assert(instance == null || instance  == Expression.empty);
    //        return this;
    //    }

    //    /// <summary>
    //    /// 存储当前符号的值，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="value">要设置的值表达式。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.setValue(ResolveContext context, Expression instance, Expression value, Node srcNode) {
    //        Debug.Assert(instance == null || instance  == Expression.empty);
    //        Compiler.error(ErrorCode.none, "无法向“this”赋值；只能向局部变量、参数、字段、属性或索引器赋值", srcNode);
    //        return null;
    //    }

    //    /// <summary>
    //    /// 载入当前符号的地址，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.addressOf(ResolveContext context, Expression instance, Node srcNode) {
    //        Debug.Assert(instance == null || instance  == Expression.empty);
    //        return new ResolvedAddressOfThisExpression() {
    //            target = this
    //        };
    //    }

    //    /// <summary>
    //    /// 调用当前符号，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="arguments">调用的参数。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.invoke(ResolveContext context, Expression instance, FuncCallExpression.Argument arguments, Node srcNode) {
    //        Debug.Assert(instance == null || instance  == Expression.empty);
    //        Compiler.error(ErrorCode.none, "无法在此上下文调用“this”", srcNode);
    //        return null;
    //    }

    //}

    ///// <summary>
    ///// 表示 base 常量。
    ///// </summary>
    //public partial class BaseLiteral : ISymbol {

    //    /// <summary>
    //    /// 载入当前符号的值，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.getValue(ResolveContext context, Expression instance, Node srcNode) {
    //        Debug.Assert(instance == null || instance  == Expression.empty);
    //        Compiler.error(ErrorCode.none, "无法获取“base”的值；请使用“this”代替", srcNode);
    //        return null;
    //    }

    //    /// <summary>
    //    /// 存储当前符号的值，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="value">要设置的值表达式。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.setValue(ResolveContext context, Expression instance, Expression value, Node srcNode) {
    //        Debug.Assert(instance == null || instance  == Expression.empty);
    //        Compiler.error(ErrorCode.none, "无法向“base”赋值；只能向局部变量、参数、字段、属性或索引器赋值", srcNode);
    //        return null;
    //    }

    //    /// <summary>
    //    /// 载入当前符号的地址，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.addressOf(ResolveContext context, Expression instance, Node srcNode) {
    //        Debug.Assert(instance == null || instance  == Expression.empty);
    //        Compiler.error(ErrorCode.none, "无法获取“base”的地址；请使用“this”代替", srcNode);
    //        return null;
    //    }

    //    /// <summary>
    //    /// 调用当前符号，返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="context">包含所有解析状态的上下文对象。</param>
    //    /// <param name="instance">当前的实例对象。如果不存在则为 null。</param>
    //    /// <param name="arguments">调用的参数。</param>
    //    /// <param name="srcNode">引发本次操作的原始语法树节点，用于报错时提示正确的位置。</param>
    //    /// <returns>返回代表此操作的表达式。</returns>
    //    Expression ISymbol.invoke(ResolveContext context, Expression instance, FuncCallExpression.Argument arguments, Node srcNode) {
    //        Debug.Assert(instance == null || instance  == Expression.empty);
    //        Compiler.error(ErrorCode.none, "无法在此上下文调用“base”", srcNode);
    //        return null;
    //    }

    //}

    #endregion

}
